package com.chuangke.framework.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuangke.admin.data.builder.UserDataBuilder;
import com.chuangke.common.constant.CacheKeyConstants;
import com.chuangke.common.data.builder.DataBuildConfig;
import com.chuangke.common.data.builder.DataBuilder;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.db.page.PageUtil;
import com.chuangke.framework.model.BasicModel;
import com.chuangke.framework.service.GridDictModelService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GridDictModelServiceImpl<M extends ServiceImpl<?, T>, T extends BasicModel>
		implements GridDictModelService<T> {

	@Autowired
	protected M daoService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	public void save(T record) {
		daoService.saveOrUpdate(record);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	public void save(List<T> records) {
		daoService.saveOrUpdateBatch(records);
	}

	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	public void doUpdateBatch(List<T> list) {
		daoService.updateBatchById(list);
	}

	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	@Override
	public void delete(T record) {
		daoService.removeById(record);
	}

	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	@Override
	public void delete(List<T> records) {
		daoService.removeBatchByIds(records);
	}

	@Transactional(rollbackFor = Throwable.class)
	@CacheEvict(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	@Override
	public void deleteByIds(List<String> ids) {
		daoService.removeByIds(ids);
	}

	@Cacheable(cacheNames = CacheKeyConstants.DICT_CACHE, keyGenerator = "commonCacheKeyGenerator")
	@Override
	public Map<String, T> findMap() {
		List<T> list = daoService.list();
		DataBuilder.of(list).appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
				new DataBuildConfig("updatedBy", "updatedByName")).build();
		return list.stream().collect(Collectors.toMap(T::getId, a -> a));
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List<T> findList() {
		Map<String, T> map = ((GridDictModelService) AopContext.currentProxy()).findMap();
		return new ArrayList<>(map.values());
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public T findById(String id) {
		if (id == null) {
			return null;
		}

		Map<String, T> map = ((GridDictModelService) AopContext.currentProxy()).findMap();
		return map.get(id);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public IPage<T> page(CkPageQuery page) {
		List<T> list = ((GridDictModelService) AopContext.currentProxy()).findList();
		return PageUtil.findPage(page, list);
	}
}
